/***********************************************************************
    filename:   DaterCalendarMonth.cpp
    created:    21/4/2012
    author:     4Ys

    purpose:    Implement the month class used in calendar
*************************************************************************/

#include "DaterCalendarMonth.h"

#include <time.h>

namespace Dater
{
	//----------------------------------------------------------------------------//
	CalendarMonth::CalendarMonth(int year, int month) :
	_year(year), _month(month)
	{
		//generate the base weekday of the first day of the given year and month
		int baseWeekDay;
		int baseYearDay;
		tm* temTm = new tm();

		temTm->tm_hour = 0;
		temTm->tm_sec = 0;
		temTm->tm_min = 0;

		temTm->tm_mday = 1;
		temTm->tm_mon = month - 1;
		temTm->tm_year = year - 1900;

		time_t temTime = mktime(temTm);
		localtime_s(temTm, &temTime);

		baseWeekDay = temTm->tm_wday + 1;

		baseYearDay = 0;

		delete temTm;

		//initialize the prototype CalendayDay object
		CalendarDay* protoDay = new CalendarDay(_year, _month,1 , baseWeekDay, baseYearDay);

		switch(_month)
		{
		case 1: case 3: case 5: case 7: case 8: case 10: case 12: _dayNum = 31; break;
		case 4: case 6: case 9: case 11: _dayNum = 30; break;
		default: _dayNum = 28; break;
		}

		//judge whether this year is a leap year
		if( (_month == 2) && ( ( (_year % 4 == 0) && (_year % 100 != 0) ) || (_year % 400 ==0) ) )
		{
			_dayNum++;
		}

		//_days[0] contains nothing
		_days.push_back(NULL);
		_days.push_back(protoDay);

		CalendarDay* commonDP;
		for(unsigned int index1 = 2; index1 <= _dayNum; index1++)
		{
			commonDP = protoDay->Clone();

			baseWeekDay = baseWeekDay == 7 ? 1 : baseWeekDay + 1;
			commonDP->setDay(index1);
			commonDP->setWeekDay(baseWeekDay);

			_days.push_back(commonDP);
		}
	}

	//----------------------------------------------------------------------------//
	CalendarMonth::~CalendarMonth()
	{
		CalendarDay* commonDP;
		for(unsigned int index1 = 1; index1 <= _dayNum; index1++)
		{
			commonDP = _days[index1];
			delete commonDP;
		}
	}

	//----------------------------------------------------------------------------//
	int CalendarMonth::getYear()
	{
		return _year;
	}

	//----------------------------------------------------------------------------//
	int CalendarMonth::getMonth()
	{
		return _month;
	}

	//----------------------------------------------------------------------------//
	CalendarDay* CalendarMonth::getDayCalendar(int day)
	{
		if(day >= 1 && day <=_dayNum)
			return _days[day];

		return NULL;
	}

	//----------------------------------------------------------------------------//
	int CalendarMonth::getDayNum()
	{
		return _dayNum;
	}

	//----------------------------------------------------------------------------//
	void CalendarMonth::addEvent(Event* _event)
	{
		tm* s = _event->getStartTime().getTime();
		tm* e = _event->getFinishTime().getTime();

		int s_day = (s->tm_year + 1900 == _year && s->tm_mon + 1 == _month) ? s->tm_mday : 1;
		int e_day = (e->tm_year + 1900 == _year && e->tm_mon + 1 == _month) ? e->tm_mday : _dayNum;

		while(s_day <= e_day)
		{
			_days[s_day]->addEvent(_event);
			s_day++;
		}
	}

	void CalendarMonth::deleteEvent(Event* _event)
	{
		tm* s = _event->getStartTime().getTime();
		tm* e = _event->getFinishTime().getTime();

		int s_day = (s->tm_year + 1900 == _year && s->tm_mon + 1 == _month) ? s->tm_mday : 1;
		int e_day = (e->tm_year + 1900 == _year && e->tm_mon + 1 == _month) ? e->tm_mday : _dayNum;

		while(s_day <= e_day)
		{
			_days[s_day]->deleteEvent(_event);
			s_day++;
		}
	}
}